package com.adjy.pathbuilders.scenario.internal;

import static com.adjy.pathbuilders.commons.Preconditions.checkNotNull;

import com.adjy.pathbuilders.commons.InvalidSourceException;
import com.adjy.pathbuilders.scenario.ScenarioObject;
import com.adjy.pathbuilders.scenario.ScenarioObjectType;
import com.adjy.pathbuilders.scenario.Position;

/**
 * A simple implementation of a {@link ScenarioObject}.
 */
public class DefaultScenarioObject implements ScenarioObject {

	private Position position;
	private ScenarioObjectType type;
	
	private static final String FIELD_SEPARATOR = "-";
	
	public DefaultScenarioObject(Position position, ScenarioObjectType type) {
		checkNotNull(position, "position must not be null.");
		checkNotNull(type, "type must not be null.");

		this.position = position;
		this.type = type;
	}

	@Override
	public Position position() {
		return position;
	}

	@Override
	public void position(Position position) {
		checkNotNull(position, "position must not be null.");
		this.position = position;
	}
	
	@Override
	public String toStore() {
		return type.toStore() + FIELD_SEPARATOR + position.toStore();
	}
	
	/**
	 * Generates a {@link ScenarioObject} from the given source. The {@link String}
	 * source must be generated by the toStore method of this class or follow the 
	 * same pattern.
	 * @param source the {@link String} source.
	 * @return a new {@link ScenarioObject}
	 * @throws InvalidSourceException if any element is missing. This may occur if
	 * the given source was not generated using the pattern used by toStore.
	 */
	public static ScenarioObject load(String source) throws InvalidSourceException {
		checkNotNull(source, "source must not be null.");
		
		String[] tokens = source.split(FIELD_SEPARATOR);
		checkTokens(source, tokens);
		
		Position position = DefaultPosition.load(tokens[1]);
		ScenarioObjectType type = ScenarioObjectType.load(tokens[0]);
		return new DefaultScenarioObject(position, type);
	}

	private static void checkTokens(String source, String[] tokens)
			throws InvalidSourceException {
		if (tokens.length != 2) {
			throw new InvalidSourceException(source);
		}
	}
	
	@Override
	public ScenarioObjectType getType() {
		return type;
	}
}
